import { HeadersType, HttpRequest, HttpRow, Methods, HttpResult } from "@/http";
import { BasicTaleBox } from "../basic-table-box";
import { RequestOptions, ResultField } from "./types";
import { signReplace } from "../utils";

type CallbackType = ((...args: any) => Record<string, any>) | undefined;
type PageType = { page: number; pageSize: number };

/** 请求类 */
class ReqPageData<T> {
	constructor(
		/** 表格实例 */
		private instance: BasicTaleBox<T>,
		/** 资源地址 */
		private url: string,
		/** 远程数据存储字段 */
		private resultField: ResultField,
		/** 请求头 */
		private headerType: HeadersType = HeadersType.Urlencoded,
		/** 请求方式 */
		private method: Methods,
		/** 是否合并参数 */
		private mergeParams: boolean,
		/** 响应数据过滤 */
		private filterData?: RequestOptions<T>["filterData"],
		/** 搜索参数过滤 */
		private filterSearchData: CallbackType = undefined,
		/** url 路径参数扩展 */
		private otherCodeReplace: CallbackType | undefined = undefined
	) {}

	async requestPageData(pageConfig: PageType, getParam: () => Record<string, any>, url?: string) {
		const sendUrl = this.parserUrl(url || this.url, pageConfig, getParam);
		const params = this.getSearchData(pageConfig, getParam, {
			pageSize: pageConfig.pageSize,
			page: pageConfig.page,
		});
		const method = this.method.toLowerCase();
		// @ts-ignore
		const res = await new HttpRequest<HttpResult<T>>(sendUrl, {
			header: this.headerType,
		})[method](params);

		if (res.code == 200) {
			const newRows = this.filterData && this.filterData(res[this.resultField]! || []);
			this.instance.setTableSource(newRows || res[this.resultField] || []);
			if (res[this.resultField].total == undefined) {
				this.instance.setDispalyPaginator(false);
			} else {
				this.instance.setTotal(Number(res[this.resultField].total));
			}
		}
		return params;
		// const newRows =
		// 	this.filterData && this.filterData(res.result.list! || []);
		// this.instance.setTableSource(newRows! || res.result.list! || []);
		// this.instance.setTotal(Number(res.result.total));
		// return params;
	}

	/** 处理搜索参数 */
	private getSearchData(
		pageConfig: PageType,
		getParam: () => Record<string, any>,
		pageLowerConfig: Record<string, any> // 小写的分页信息
	) {
		const param = Object.values(getParam()).reduce((prev, obj) => {
			return { ...prev, ...obj };
		}, {});
		const baseParams = { ...pageConfig, ...param, ...pageLowerConfig };
		const params = this.filterSearchData ? this.filterSearchData(baseParams) : baseParams;

		return this.mergeParams ? { ...baseParams, ...params } : params;
	}

	/** 处理请求路径 */
	private parserUrl(url: string, pageConfig: PageType, getParam: () => Record<string, any>) {
		let curUrl: string = url;
		const { page, pageSize } = pageConfig;
		const expand = this.otherCodeReplace && this.otherCodeReplace(getParam());
		if (expand) {
			Object.keys(expand).forEach(key => (curUrl = signReplace(curUrl, key, expand[key])));
		}
		curUrl = signReplace(curUrl, "page", page.toString());
		curUrl = signReplace(curUrl, "pageSize", pageSize.toString());

		return curUrl;
	}
}

export { ReqPageData };
